/*
 * �쐬��: 2008/07/31
 *
 * ���̐������ꂽ�R�����g�̑}����e���v���[�g��ύX���邽��
 * �E�B���h�E > �ݒ� > Java > �R�[�h���� > �R�[�h�ƃR�����g
 */
package sort.ui.components;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import sort.algorithm.Sorter;
import sort.record.RandomRecordsFactory;
import sort.record.Records;
import sort.record.RecordsFactory;
import sort.result.SortResult;
import sort.result.SortResultWatcher;

/**
 * @author masaru-gotou
 *
 */
@SuppressWarnings("serial")
public class SortControlWindow extends JFrame implements Observer,ActionListener {
	private Sorter sorter;
	private Records records;
	private SortAnimationPanel vpanel;
	private SelectorPanel spanel;
	private ResultPanel rpanel;
	private JButton b_start;
	private JButton b_init;
	private SortResult result;
	
	public SortControlWindow(String title) {
		super(title);
		setSize(400,400);
		Container container = getContentPane();
//		container.setLayout(new GridLayout(3,1));
		container.setLayout(new BorderLayout());
		
		this.spanel = new SelectorPanel();
		
		JPanel cpanel = new JPanel(new FlowLayout());
		b_init = new JButton("Init");
		cpanel.add(b_init);
		
		b_start = new JButton("Start");
		cpanel.add(b_start);
//		b_start.addActionListener(this);
//		b_init.addActionListener(this);
		
		this.vpanel = new SortAnimationPanel();
		this.rpanel = new ResultPanel();
		
		container.add(BorderLayout.NORTH, spanel);
		container.add(BorderLayout.EAST, cpanel);
		container.add(BorderLayout.CENTER, vpanel);
		container.add(BorderLayout.SOUTH, rpanel);
		
//		pack();
		
//		init();
	}
	
	public void addInitActionListener(ActionListener l) {
		b_init.addActionListener(l);
	}
	public void addStartActionListener(ActionListener l) {
		b_start.addActionListener(l);
	}
	
	public void setAlgorithmNames(String[] names) {
		spanel.setAlgorithmNames(names);
	}
	protected void init() {
//		RecordsFactory factory = FixedRecordsFactory.getInstance();
		RecordsFactory factory = RandomRecordsFactory.getInstance();
		
		records = factory.create(spanel.getRecordCount());
		vpanel.drawRecords(records);
		
		try {
			sorter = (Sorter)Class.forName(spanel.getArgorythmName()).newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		sorter.addObserver(this);
	}

	protected void start() {
		SortResultWatcher watcher = new SortResultWatcher(sorter.getName());
		watcher.start(records);
		Records sorted = sorter.sort(records.copy());
		watcher.finish(sorted);
		result = watcher.getResult();
		rpanel.setArgorythmName(result.getAlgorithmName());
		rpanel.setSorted(result.isSorted());
		rpanel.setStabled(result.isStabled());
		rpanel.setTime(result.getElapsedTime());
		rpanel.setValidated(result.isValidated());
		rpanel.setMemoryUsage(result.getUsedMemory());
	}

	@Override
	public void update(Observable o, Object arg) {
		vpanel.drawRecords((Records)arg);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if ( e.getSource() == b_start ) start();
		if ( e.getSource() == b_init ) init();
	}
	
	public void setResult(SortResult result) {
		rpanel.setArgorythmName(result.getAlgorithmName());
		rpanel.setSorted(result.isSorted());
		rpanel.setStabled(result.isStabled());
		rpanel.setTime(result.getElapsedTime());
		rpanel.setValidated(result.isValidated());
		rpanel.setMemoryUsage(result.getUsedMemory());
	}
	public String getAlgorithmName() {
		return spanel.getArgorythmName();
	}

	public int getRecordCount() {
		return spanel.getRecordCount();
	}

	public void drawRecords(Records records) {
		vpanel.drawRecords(records);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				SortControlWindow main = new SortControlWindow("Sort Demo");
				main.setVisible(true);
			}
		});
	}

}
